﻿/*========================== 
 * @author 郑金泉
 * @desc 实体枚举字段类
 * @created 2014-05-22
 * ========================= */
using System;
using System.Collections.Generic;
using System.Text;

namespace Obsidian.Edm
{
    /// <summary>
    /// 枚举字段
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    public class EnumField<T> : ModelField, IModelField where T : struct
    {

        public override FieldType Type
        {
            get { return FieldType.Enum; }
        }

        private EnumFieldToStringCase _toStringCase = EnumFieldToStringCase.NotChange;
        /// <summary>
        /// ToString方法返回的大小写形式
        /// </summary>
        public EnumFieldToStringCase ToStringCase
        {
            get { return this._toStringCase; }
        }

        private T _value;
        /// <summary>
        /// 获取值
        /// </summary>
        public T Value
        {
            get { return this._value; }
        }

        /// <summary>
        /// 获取值
        /// </summary>
        public object OValue
        {
            get { return _value; }
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public IModel Set(object value)
        {

            if (value == null)
            {
                return this.SetNull();
            }
            else
            {
                Type valType = value.GetType();
                Type enumType = typeof(T);
                if (valType == enumType)
                {
                    return this.Set((T)value);
                }
                else if (valType == typeof(System.String))
                {
                    string strVal = Convert.ToString(value);
                    T v = (T)Enum.Parse(enumType, strVal, true);
                    return this.Set(v);
                }
                else
                {
                    throw new Exception("输入类型无法转换");
                }
            }
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public IModel Set(T value)
        {
            if (!base._assigned)
                base._assigned = true;
            this._isNull = false;
            this._value = value;
            return base.Model;
        }

        /// <summary>
        /// 设置值
        /// </summary>
        public bool TrySet(object value)
        {
            try
            {
                this.Set(value);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 设置为空值状态
        /// </summary>
        public IModel SetNull()
        {
            this._value = default(T);
            this._isNull = true;
            return base.Model;
        }


        public EnumField(IModel model)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model);
        }

        public EnumField(IModel model, EnumFieldToStringCase toStrCase)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model);
            this._toStringCase = toStrCase;
        }

        public EnumField(IModel model, string dbFieldName)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName);
        }

        public EnumField(IModel model, string dbFieldName, EnumFieldToStringCase toStrCase)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName);
            this._toStringCase = toStrCase;
        }

        public EnumField(IModel model, string dbFieldName, string alias)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName, alias);
        }

        public EnumField(IModel model, string dbFieldName, string alias, EnumFieldToStringCase toStrCase)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName, alias);
            this._toStringCase = toStrCase;
        }

        public EnumField(IModel model, string dbFieldName, string alias, T defaultValue)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName, alias);
            this.Set(defaultValue);

        }

        public EnumField(IModel model, string dbFieldName, string alias, T defaultValue, EnumFieldToStringCase toStrCase)
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("必须是枚举类型");
            this.InitField(model, dbFieldName, alias);
            this._toStringCase = toStrCase;
            this.Set(defaultValue);

        }

        public string ToString()
        {
            if (this.IsNull)
                return null;
            string str = Enum.GetName(typeof(T), this._value);

            if (this._toStringCase == EnumFieldToStringCase.LowerCase)
                return str.ToLower();

            if (this._toStringCase == EnumFieldToStringCase.UpperCase)
                return str.ToUpper();

            return str;

        }
    }

    /// <summary>
    /// 枚举字段ToString返回的大小写形式
    /// </summary>
    public enum EnumFieldToStringCase
    {
        /// <summary>
        /// 不改变
        /// </summary>
        NotChange,
        /// <summary>
        /// 大写
        /// </summary>
        UpperCase,
        /// <summary>
        /// 小写
        /// </summary>
        LowerCase
    }
}
